#include "stretchWidget.h"
#include <BRepPrimAPI_MakePrism.hxx>
#include "BRepBuilderAPI_MakeFace.hxx"
#include "../../Opencascade/opencascade-7.8.0/src/TopExp/TopExp.hxx"

stretchWidget::stretchWidget(modelSoft* myModelSoft, QWidget* parent)
	: myModelSoft(myModelSoft)
	, QWidget(parent)
	, ui(new Ui::stretchWidgetClass())
{
	ui->setupUi(this);
	ui->modifyButton->setEnabled(false);
	ui->confirmButton->setEnabled(false);
	myModelSoft->myView->getInteractorStyle()->setStretchOperation(true);
	stretchFeature = new StretchFeature();
	stretchFeature->setStretchId(myModelSoft->shapeTag++);
	stretchFeature->setShapeId(stretchFeature->getStretchId());
	stretchFeature->setStretchType(0);
	typeTag = 0;
	isModified = false;
	createConnection();
}

stretchWidget::~stretchWidget()
{
	delete ui;
}

void stretchWidget::createConnection()
{
	connect(myModelSoft->currFaceSelector, &OccFaceSelector::sentStretchSubShape, this, &stretchWidget::receiveStretchSelectedShape);
	connect(myModelSoft->currVertexSelector, &OccVertexSelector::sentStretchSubShape, this, &stretchWidget::receiveStretchSelectedShape);
	connect(myModelSoft->currShapeSelector, &OccShapeSelector::sentStretchSubShape, this, &stretchWidget::receiveStretchSelectedShape);
	connect(myModelSoft->currEdgeSelector, &OccEdgeSelector::sentStretchSubShape, this, &stretchWidget::receiveStretchSelectedShape);
	connect(ui->modifyButton, &QPushButton::clicked, this, &stretchWidget::onClickModify);
	connect(ui->confirmButton, &QPushButton::clicked, this, &stretchWidget::onClickConfirm);
	connect(ui->cancelButton, &QPushButton::clicked, this, &stretchWidget::close);
	connect(ui->selectButton, &QPushButton::clicked, this, &stretchWidget::onClickSelect);
	connect(ui->typeSelect, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &stretchWidget::typeChange);
}

void stretchWidget::onClickModify()
{
	gp_Vec stretchDirection(ui->pxInput->text().toDouble(), ui->pyInput->text().toDouble(), ui->pzInput->text().toDouble());
	stretchFeature->setStretchVec(stretchDirection);
	//判断拉伸方向是否有效
	if (!(IsNearlyZero(stretchDirection.X()) && IsNearlyZero(stretchDirection.Y()) && IsNearlyZero(stretchDirection.Z()))) {
		auto type = selectShape.ShapeType();
		const TopoDS_Shape& newShape = BRepPrimAPI_MakePrism(selectShape, stretchDirection);
		
		resultPipeline = myModelSoft->CreatePipeline(newShape, stretchFeature->getStretchId(), true);
		stretchFeature->setResultId(resultPipeline->GetShapeID());
		//selectPipeline->SetPipelineVisibility(false);
		myModelSoft->myView->getRenderWindow()->Render();
		isModified = true;
		ui->confirmButton->setEnabled(true);
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,255,255)");
		myModelSoft->myView->getInteractorStyle()->clearCurrSelector();
		/*isModified = false;
		typeTag = 0;
		selectShape = TopoDS_Shape();
		ui->modifyButton->setEnabled(false);
		ui->confirmButton->setEnabled(false);*/
	}
}

void stretchWidget::closeEvent(QCloseEvent* event)
{
	// 清除已选择的Actor
	myModelSoft->myView->getInteractorStyle()->clearCurrSelector();
	myModelSoft->myView->getInteractorStyle()->setStretchOperation(false);
	// 没有点确定，删除创建的Actor
	if (!confirmCreated)
	{
		if (!resultPipeline.IsNull())
		{
			myModelSoft->RemovePipelineFromRenderer(resultPipeline);
			myModelSoft->myView->getRenderWindow()->Render();
		}
	}
}

void stretchWidget::onClickConfirm()
{
	QStandardItem* item1 = new QStandardItem(QString("拉伸-%1").arg(stretchFeature->getStretchId()));
	int row = myModelSoft->ui->model->rowCount();
	item1->setEditable(false);
	myModelSoft->ui->model->setItem(row, 0, item1);
	QStandardItem* item2 = new QStandardItem(QString("隐藏"));
	item2->setCheckable(true);
	myModelSoft->ui->model->setItem(row, 1, item2);
	myModelSoft->m_Features.insert(std::pair<Standard_Integer, StretchFeature*>(stretchFeature->getStretchId(), stretchFeature));
	confirmCreated = true;
	
	close();
}


void stretchWidget::onClickSelect()
{
	if (typeTag == 0) {
		myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Vertex);
		myModelSoft->changeSelector(SM_Vertex);
		myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
		stretchFeature->setStretchType(0);
	}else if (typeTag == 1) {
		myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Edge);
		myModelSoft->changeSelector(SM_Edge);
		myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
		stretchFeature->setStretchType(1);
	}else {
		myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Face);
		myModelSoft->changeSelector(SM_Face);
		myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
		stretchFeature->setStretchType(2);
	}
}

void stretchWidget::onClickCancelSelect()
{
	// 已经修改不能取消选中
	if (!selectShape.IsNull() && !isModified)
	{
		myModelSoft->currSelector->deleteSelectedShape(selectShape);
		selectShape = TopoDS_Shape();
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,255,255)");
		ui->modifyButton->setEnabled(false);
		targetReceive = false;
	}
}

void stretchWidget::typeChange(int type)
{
	typeTag = type;
}

void stretchWidget::receiveStretchSelectedShape(const TopoDS_Shape& subShape, Handle(QIVtkSelectionPipeline) pipeline)
{
	if (!targetReceive) {
		auto iter = myModelSoft->m_Features.find(pipeline->GetShapeID());
		if (iter == myModelSoft->m_Features.end()) {
			return;
		}
		stretchFeature->setTargetFeature(iter->second);
		switch (typeTag) {
		case 0:
		{
			selectShape = TopoDS::Vertex(subShape);
			//查找选择边在父对象的索引值
			//映射容器，用于存储 TopoDS_Shape 对象的索引映射
			TopTools_IndexedMapOfShape M;
			//遍历 S 中的所有边	将边的索引添加到 M 中
			TopExp::MapShapes(pipeline->getShape(), TopAbs_VERTEX, M);
			int count = M.Extent();
			while (count >= 0) {
				if (M.FindKey(count).IsEqual(subShape)) {
					stretchFeature->setSubShapeIndex(count);
					break;
				}
				count--;
			}
			break;
		}
		case 1:
		{
			selectShape = TopoDS::Edge(subShape);
			//查找选择边在父对象的索引值
			//映射容器，用于存储 TopoDS_Shape 对象的索引映射
			TopTools_IndexedMapOfShape M;
			//遍历 S 中的所有边	将边的索引添加到 M 中
			TopExp::MapShapes(pipeline->getShape(), TopAbs_EDGE, M);
			int count = M.Extent();
			while (count >= 0) {
				if (M.FindKey(count).IsEqual(subShape)) {
					stretchFeature->setSubShapeIndex(count);
					break;
				}
				count--;
			}
			break;
		}
		case 2:
		{
			TopoDS_Shape newShape;
			if (subShape.ShapeType() == TopAbs_WIRE) {
				newShape = BRepBuilderAPI_MakeFace(TopoDS::Wire(subShape));
			}
			else {
				newShape = subShape;
			}
			selectShape = TopoDS::Face(newShape);
			//查找选择边在父对象的索引值
			//映射容器，用于存储 TopoDS_Shape 对象的索引映射
			TopTools_IndexedMapOfShape M;
			//遍历 S 中的所有边	将边的索引添加到 M 中
			TopExp::MapShapes(pipeline->getShape(), TopAbs_WIRE, M);
			int count = M.Extent();
			while (count >= 0) {
				if (M.FindKey(count).IsEqual(subShape)) {
					stretchFeature->setSubShapeIndex(count);
					break;
				}
				count--;
			}
			break;
		}
		}
		ui->modifyButton->setEnabled(true);
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,178,102)");
		targetReceive = true;
	}
}
